import React, { useState, useEffect, useRef } from 'react';
import { Checkbox, Input, Tree } from 'antd';
// @ts-ignore
import Empty from '@/tool/components/PageEmpty';
import { CloseOutlined } from '@ant-design/icons';
import {
  getAllMarketingUnit,
  filterTreeDataByKeyword,
  getCheckKeys,
  findParentsKeys,
} from '../utils';
import _ from 'lodash';
import type { DataNode, TreeProps } from 'antd/lib/tree';
import type { Key } from 'react';
import './index.less';

const { Search } = Input;

const SelectMarketingUnit: React.FC<ISelectMarketingUnitProps> = (props) => {
  const [treeData, setTreeData] = useState<DataNode[]>([]);
  const [checkedKeys, setCheckedKeys] = useState<TreeProps['checkedKeys']>([]);
  const [checkedRows, setCheckedRows] = useState<DataNode[]>([]);
  const [checkAll, setCheckAll] = useState<boolean>(false);
  const [indeterminate, setIndeterminate] = useState<boolean>(false);
  const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);
  const allMarketingUnit = useRef<DataNode[]>([]);
  const newAllTreeData = useRef<DataNode[]>([]);
  const currentMarketingUnitList = useRef<DataNode[]>([]);
  const searchStr = useRef<string>();

  const onChangeAll = (checked: boolean) => {
    if (checked) {
      let arr = [...allMarketingUnit.current];
      if (searchStr.current) {
        arr = [...currentMarketingUnitList.current];
      }
      setCheckedKeys(arr.map((v) => v.key));
      setCheckedRows(arr);
      setIndeterminate(false);
    } else {
      if (searchStr.current) {
        const rows = [...checkedRows];
        currentMarketingUnitList.current.forEach((v: DataNode) => {
          _.remove(rows, (n: DataNode) => n.key === v.key);
        });
        setCheckedRows(rows);
      } else {
        setCheckedRows([]);
      }
      setCheckedKeys([]);
    }
    setCheckAll(checked);
  };

  const onSearch = (val: string) => {
    let marketingUnit = allMarketingUnit.current;
    searchStr.current = val;
    if (val) {
      const result = filterTreeDataByKeyword([...newAllTreeData.current], val);
      marketingUnit = getAllMarketingUnit(result.newTreeData);
      currentMarketingUnitList.current = marketingUnit;
      setTreeData(result.newTreeData);
      setExpandedKeys(result.expandedKeys);
    } else {
      setTreeData(newAllTreeData.current);
      setExpandedKeys([]);
    }

    if (checkedRows.length > 0) {
      const { checkedKeys, checkAll, indeterminate } = getCheckKeys(marketingUnit, checkedRows);
      setCheckAll(checkAll);
      setCheckedKeys(checkedKeys);
      setIndeterminate(indeterminate);
    }
  };

  const clearSelectData = (key?: Key) => {
    if (key) {
      let keys = [...(checkedKeys as Key[])];
      let rows = [...checkedRows];
      const parentsKeys = findParentsKeys(treeData, key);

      keys = _.remove(keys, (n: Key) => n !== key && !parentsKeys.includes(n));

      rows = _.remove(rows, (n: DataNode) => n.key !== key);
      if (searchStr.current) {
        const { indeterminate, checkAll } = getCheckKeys(currentMarketingUnitList.current, rows);
        setCheckAll(checkAll);
        setIndeterminate(indeterminate);
      } else {
        if (rows.length < allMarketingUnit.current.length && rows.length > 0) {
          setIndeterminate(true);
        }
        setCheckAll(false);
      }
      setCheckedKeys(keys);
      setCheckedRows(rows);
    } else {
      setCheckedKeys([]);
      setCheckedRows([]);
      setCheckAll(false);
    }
  };

  const onCheckTree: TreeProps['onCheck'] = (keys, e) => {
    const node = e.node;
    let marketingUnit: DataNode[] = [];
    const rows: DataNode[] = [...checkedRows];
    if (node.children && node.children.length > 0) {
      // 改 性能差
      const children = getAllMarketingUnit(node.children);
      const newMarketingUnit: DataNode[] = [];
      children.forEach((v) => {
        const item = _.find(allMarketingUnit.current, (n: DataNode) => n.key === v.key);
        if (item) {
          newMarketingUnit.push(item);
        }
      });
      marketingUnit = newMarketingUnit;
    } else {
      const item = _.find(allMarketingUnit.current, (n: DataNode) => n.key === node.key);
      marketingUnit = [{ key: item.key, title: item.title }];
    }
    if (e.checked) {
      rows.unshift(...marketingUnit);
    } else {
      marketingUnit.forEach((v) => {
        _.remove(rows, (n: DataNode) => n.key === v.key);
      });
    }
    setCheckedRows(_.uniqBy(rows, 'key'));
    setCheckedKeys(keys as Key[]);
  };

  const changeAllCheckStatus = () => {
    const checkLength = checkedRows.length;
    let arr = allMarketingUnit.current;
    let check = false;
    let indeterminate = false;
    if (checkLength > 0) {
      if (searchStr.current) {
        arr = currentMarketingUnitList.current;
        const obj = getCheckKeys(arr, checkedRows);
        check = obj.checkAll;
        indeterminate = obj.indeterminate;
      } else {
        if (arr.length <= checkLength) {
          check = true;
        }
        if (checkLength > 0 && checkLength < arr.length) {
          indeterminate = true;
        }
      }
    }
    setCheckAll(check);
    setIndeterminate(indeterminate);
  };

  const setValue = (value: Key[], marketingUnit: DataNode[]) => {
    const rows: DataNode[] = [];
    value.forEach((v) => {
      const item = _.find(marketingUnit, (n: DataNode) => n.key === v);
      rows.push(item);
    });
    setCheckedKeys(value);
    setCheckedRows(rows);
  };

  useEffect(() => {
    changeAllCheckStatus();
  }, [checkedRows.length]);

  useEffect(() => {
    if (props.treeData && props.treeData.length > 0) {
      newAllTreeData.current = props.treeData;
      allMarketingUnit.current = props.marketingUnit
        ? props.marketingUnit
        : getAllMarketingUnit(props.treeData);
      if (props.value && props.value.length > 0) {
        setValue(props.value, allMarketingUnit.current);
      }
      setTreeData(props.treeData);
    }
  }, [props.treeData, props.value]);

  useEffect(() => {
    props.getHandler(() => checkedRows);
  });

  return (
    <div className="select-marketing-unit">
      <div className="left">
        <div className="search-box">
          <Search placeholder="搜索" onSearch={onSearch} />
          {treeData.length > 0 && (
            <Checkbox
              onChange={(e) => onChangeAll(e.target.checked)}
              checked={checkAll}
              indeterminate={indeterminate}
            >
              全选
            </Checkbox>
          )}
        </div>
        <div className="list">
          {treeData.length > 0 ? (
            <Tree
              checkable
              treeData={treeData}
              checkedKeys={checkedKeys}
              expandedKeys={expandedKeys}
              onExpand={(keys) => setExpandedKeys(keys)}
              onCheck={onCheckTree}
            />
          ) : (
            <Empty />
          )}
        </div>
      </div>
      <div className="right">
        <div className="opt">
          <div className="length">已选{checkedRows.length}项</div>
          <div className="clear" onClick={() => clearSelectData()}>
            清空
          </div>
        </div>
        <div className="list">
          {checkedRows.map((v) => {
            return (
              <div className="check-item" key={v.key}>
                {v.title} <CloseOutlined onClick={() => clearSelectData(v.key)} />
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

interface ISelectMarketingUnitProps {
  /**
   * 默认选中的数据
   */
  value?: Key[];
  /**
   * 树形结构数据
   */
  treeData?: DataNode[];
  /**
   * 当前交易单元
   */
  marketingUnit?: DataNode[];

  getHandler?: any;
}

export default SelectMarketingUnit;
